package com.liwenfeng.diancanspringboot.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.liwenfeng.diancanspringboot.common.exception.OrderBusinessException;
import com.liwenfeng.diancanspringboot.common.result.PageResult;
import com.liwenfeng.diancanspringboot.mapper.OrderDetailMapper;
import com.liwenfeng.diancanspringboot.mapper.OrderMapper;
import com.liwenfeng.diancanspringboot.mapper.ShoppingCartMapper;
import com.liwenfeng.diancanspringboot.mapper.TurnoverMapper;
import com.liwenfeng.diancanspringboot.pojo.dto.TurnoverPageDTO;
import com.liwenfeng.diancanspringboot.pojo.entity.OrderDetail;
import com.liwenfeng.diancanspringboot.pojo.entity.Orders;
import com.liwenfeng.diancanspringboot.pojo.entity.Turnover;
import com.liwenfeng.diancanspringboot.pojo.vo.TurnoverVO;
import com.liwenfeng.diancanspringboot.service.TurnoverService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
public class TurnoverServiceImpl implements TurnoverService {
    @Autowired
    private TurnoverMapper turnoverMapper;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private ShoppingCartMapper shoppingCartMapper;

    // 查询正在使用的turnover(流水单）(手机端admin模块）
    @Override
    public List<Turnover> getDoingList() {
        List<Turnover> doingList = turnoverMapper.getTurnoversDoing();
        return doingList;
    }


    // 清台(手机端admin模块）
    @Override
    @Transactional
    public void update(Turnover turnover) {
        if (turnover.getStatus() == null) {
            throw new OrderBusinessException("参数错误，请刷新后重试");
        }
        Turnover byId = turnoverMapper.getById(turnover.getId());
        if (byId==null){
            throw new OrderBusinessException("流水单不存在，请刷新后重试");
        }
        if (Objects.equals(byId.getStatus(), Turnover.STATUS_DONE)){
            throw new OrderBusinessException("该桌未被使用，或已经清台，不需要操作");
        }
        if(turnover.getPlace()!=null&& !Objects.equals(byId.getPlace(), turnover.getPlace())){
            throw new OrderBusinessException(turnover.getPlace()+"号桌换桌了，请刷新后重试");
        }
        List<Orders> allOrdersList = orderMapper.getAllTurnoverId(turnover.getId());
        List<Orders> ordersList = orderMapper.getUnpayByTurnoverId(turnover.getId());

        if (allOrdersList.size() == ordersList.size()) {
            if (!ordersList.isEmpty()) {
                // 判断是否有除"餐具”以外的未结账订单
                boolean hasUnpaidOrder = ordersList.stream()
                        .flatMap(order -> orderDetailMapper.getValidByOrderId(order.getId()).stream())
                        .anyMatch(orderDetail -> !"餐具".equals(orderDetail.getName()));
                if (hasUnpaidOrder) {
                    throw new OrderBusinessException("该桌有未结账订单，不能清台");
                } else {
                    ordersList.forEach(orders -> {
                        Orders orders1 = new Orders();
                        orders1.setId(orders.getId());
                        orders1.setStatus(Orders.CANCELLED);
                        orders1.setAmount(BigDecimal.valueOf(0));
                        orders1.setCancelTime(LocalDateTime.now());
                        orderMapper.update(orders1);
                        OrderDetail orderDetail = new OrderDetail();
                        orderDetail.setOrderId(orders.getId());
                        orderDetail.setStatus(OrderDetail.CANCELLED);
                        orderDetailMapper.update(orderDetail);
                    });
                }
            }
        } else {
            if (!ordersList.isEmpty()) {
                throw new OrderBusinessException("该桌有未结账订单，不能清台");
            }
        }
        shoppingCartMapper.deleteByturnoverId(turnover.getId());
        turnoverMapper.update(turnover);
    }

    // 换桌(手机端admin模块）
    @Override
    @Transactional
    public void changePlace(Map<String, Long> map) {
        Integer fromPlace = Math.toIntExact(map.get("fromPlace"));
        Integer toPlace = Math.toIntExact(map.get("toPlace"));
        Long turnoverId = map.get("turnoverId");
        Turnover currentTurnover = null;

        List<Turnover> turnoversDoing = turnoverMapper.getTurnoversDoing();
        for (Turnover turnover : turnoversDoing) {
            if (Objects.equals(turnover.getPlace(), toPlace)) {
                throw new OrderBusinessException(toPlace + "号桌已被占用，请结账后刷新重试");
            }
            if (Objects.equals(turnover.getPlace(), fromPlace)) {
                if (turnoverId != null && !Objects.equals(turnoverId, turnover.getId())) {
                    throw new OrderBusinessException(fromPlace + "号桌有异常，请刷新重试");
                }
                currentTurnover = turnover;
                turnoverId = turnover.getId();
            }
        }

        if (currentTurnover == null) {
            throw new OrderBusinessException(fromPlace + "号桌异常，无法换桌，请确认该桌正在被使用");
        }

        Turnover turnover = new Turnover();
        turnover.setId(turnoverId);
        turnover.setPlace(toPlace);
        turnoverMapper.update(turnover);

        // 换桌后，只更新未结账订单详情的place
        List<Orders> ordersList = orderMapper.getUnpayByTurnoverId(turnoverId);
        if (ordersList.isEmpty()) {
            return;
        }
        for (Orders orders : ordersList) {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOrderId(orders.getId());
            orderDetail.setPlace(toPlace);
            orderDetailMapper.update(orderDetail);
        }
    }

    /**
     * 流水单分页查询(浏览器端）
     *
     * @param turnoverPageDTO
     * @return PageResult
     */
    @Override
    public PageResult page(TurnoverPageDTO turnoverPageDTO) {
        PageHelper.startPage(turnoverPageDTO.getPage(), turnoverPageDTO.getPageSize());
        Page<TurnoverVO> page = turnoverMapper.selectByPage(turnoverPageDTO);
        return new PageResult(page.getTotal(), page.getResult());
    }
}
